#include <iostream>
#include <unistd.h>
#include <signal.h>

using namespace std;

void PrintPending(const sigset_t &pset)
{
    for(int i = 31; i >= 1; i--)
    {
        cout << sigismember(&pset, i);
    }
    cout << endl;
}

void handler(int signum)
{
    cout << "catch a signum: " << signum << endl;
}

int main()
{
    signal(2, handler);
    // 1. 先对 2 号信号进行屏蔽

    // 数据预备工作
    sigset_t bset, oset; 
    sigemptyset(&bset); // 先将信号集清空
    sigemptyset(&oset); // 先将信号集清空
    sigaddset(&bset, 2); // 给 bset 中添加上 2 号信号

    // 调用系统调用，将数据设置进内核
    sigprocmask(SIG_SETMASK, &bset, &oset);

    // 2. 重复打印当前进程的 pending 信号集
    // 在重复打印期间向进程发送 2 号信号，因为 2 号信号被屏蔽了，所以 2 号信号会一直被保存在 pending 中
    sigset_t pset; // pending
    sigemptyset(&pset);
    int cnt = 0;
    while(true)
    {
         int n = sigpending(&pset);
         if(n < 0) continue;
         PrintPending(pset);
         sleep(1);
         cnt++;
         if(cnt == 15)
         {
            cout << "unblock 2 signo" << endl;
            // 解除阻塞
            sigdelset(&bset, 2);
            sigprocmask(SIG_SETMASK, &oset, nullptr);
         }
    }

    return 0;
}


// void task()
// {
//     cout << "task is running" << endl;
// }

// void signal_handler(int signum) {
//     task();
//     unsigned int time = alarm(5);
//     cout << "alarm time is : " << time << endl;
// }

// int main() {
//     // 注册信号处理函数
//     signal(SIGALRM, signal_handler);

//     // 设置定时器，50秒后发送SIGALRM信号
//     alarm(50);

//     int cnt = 100;
//     while(cnt)
//     {
//         cout << "this is a process, pid is : " << getpid() << endl;
//         sleep(1);
//         cnt--;
//     }

//     return 0;
// }

// 信号处理函数
// void signal_handler(int signum) {
//     cout << "Received SIGALRM signal:" << signum << endl;
// }

// int main() {
//     // 注册信号处理函数
//     signal(SIGALRM, signal_handler);

//     // 设置定时器，5秒后发送SIGALRM信号
//     alarm(5);

//     int cnt = 15;
//     while(cnt)
//     {
//         cout << "this is a process" << endl;
//         sleep(1);
//         cnt--;
//     }

//     return 0;
// }